import React, { Fragment, useContext, useEffect, useRef, useState } from 'react';
import hoistNonReactStatics from 'hoist-non-react-statics';
import Loading from './loading';

const LoadingContext = React.createContext();

export function useLoading(config) {
    const context = useContext(LoadingContext);
    return {
        show: context.showLoading,
        hide: context.hideLoading
    };
}

export function DefaultLoading(props) {
    const ref = useRef({});
    const forceUpdate = useState()[1];

    useEffect(
        () => {
            forceUpdate({});
        },
        [ref.current]
    );

    return (
        <Fragment>
            <LoadingContext.Provider value={ref.current}>{props.children}</LoadingContext.Provider>
            <Loading ref={ref} />
        </Fragment>
    );
}

export function withHooks(InjectComponent) {
    function Enhancer(props, ref) {
        const loading = useLoading();
        return <InjectComponent {...props} ref={ref} loading={loading} />;
    }

    hoistNonReactStatics(Enhancer, InjectComponent);

    Enhancer.displayName = `EnhancerLoadingWith${getDisplayName(InjectComponent)}`;

    return React.forwardRef(Enhancer);
}

function getDisplayName(WrappedComponent) {
    return WrappedComponent.displayName || WrappedComponent.name || 'Component';
}
